<?php

/**
 * IP
 *
 * IPFactory::Instance()->getCountryCoByIP();
 */

namespace App\Tools;

use GeoIp2\Database\Reader;

class IPFactory {

	public $oGeoIP;
	public $sCountryCoDefault = 'US';

	private static $__oInstance;

	public static function Instance() {
		if(!isset(self::$__oInstance)) {
			self::$__oInstance = new self();
		}
		return self::$__oInstance;
	}

	/**
	 * 获取国家编码
	 * @param string $sIP
	 * @return string|null
	 */
	public function getCountryCoByIP($sIP = null) {
		if(empty($sIP)) {
			$sIP = $this->getClientIP(false);
		}
		if(!isset($this->oGeoIP)) {
			$this->oGeoIP = new Reader(database_path().'/mmdb/GeoLite2-Country.mmdb');
		}

		try {
			$oRecord = $this->oGeoIP->Country($sIP);
			return $oRecord->country->isoCode;
		} catch(\Exception $E) {
			//return $E->getMessage();
			return $this->sCountryCoDefault;
		}
	}

	/**
	 * 获取来源IP
	 * @param boolean $bInt
	 * @return  string
	 */
	public function getClientIP($bInt = false) {
		if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
			$sIP = getenv('HTTP_CLIENT_IP');
		} else {
			if(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
				$sIP = getenv('HTTP_X_FORWARDED_FOR');
			} else {
				if(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
					$sIP = getenv('REMOTE_ADDR');
				} else {
					if(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
						$sIP = $_SERVER['REMOTE_ADDR'];
					} else {
						$sIP = 'unknown';
					}
				}
			}
		}
		if($bInt === true) {
			return $this->IPV4ToInt($sIP);
		} else {
			return $sIP;
		}
	}

	/**
	 * 转换为整型
	 * @param string $sIP
	 * @return  int
	 */
	public function IPV4ToInt($sIP) {
		if(empty($sIP) || $sIP == 'unknown') {
			return 0;
		}
		list($sIP1, $sIP2, $sIP3, $sIP4) = explode('.', $sIP);
		return $sIP1 * pow(256, 3) + $sIP2 * pow(256, 2) + $sIP3 * 256 + $sIP4;
	}


}